﻿using LxCore;

namespace LxCore
{
    /*模型之间会有依赖关系
     * 下游的模型，即非必选的模型设置为可null类型,null时表示选项不适用。
     * 有模型改动后，全局检查模型设置
     */
    public partial class PhysicalModel : JsIdentifyItem
    {
        public PhysicalModel()
        {
            Name = "新物理模型";
            ReferenceValue = new();
            InitialValue = new();
            SolveSetting = new();
            PhysicalType = PhysicalTypes.固体;
        }
        private PhysicalTypes _PhysicalType;
        public PhysicalTypes PhysicalType
        {
            get => _PhysicalType;
            set
            {
                if (_PhysicalType != value || MaterialProperty == null)
                {
                    _PhysicalType = value;
                    switch (value)
                    {
                        case PhysicalTypes.固体:
                            MaterialProperty = MaterialLib.GetSolidDefault();
                            SolveSetting.EnergyRelaxFactor = ConstField.Double1;
                            break;
                        case PhysicalTypes.流体:
                            MaterialProperty = MaterialLib.GetFluidDefault();
                            SolveSetting.EnergyRelaxFactor = new ConstField.Double(0.9);
                            break;
                    }
                }
                RaisePropertyChanged(nameof(PhysicalType));
                CheckModelSet();
            }
        }
        public bool IsEnergyEnabled
        {
            get => _IsEnergyEnabled;
            set
            {
                _IsEnergyEnabled = value;
                RaisePropertyChanged(nameof(IsEnergyEnabled));
                CheckModelSet();
            }
        }
        private bool _IsEnergyEnabled = false;
        public FlowTypes? FlowType
        {
            get => _FlowType;
            set
            {
                _FlowType = value;
                RaisePropertyChanged(nameof(FlowType));
                CheckModelSet();
            }
        }
        private FlowTypes? _FlowType;
        public TurbulenceTypes? TurbulenceType
        {
            get => _TurbulenceType;
            set
            {
                _TurbulenceType = value;
                RaisePropertyChanged(nameof(TurbulenceType));
                CheckModelSet();
            }
        }
        private TurbulenceTypes? _TurbulenceType = TurbulenceTypes.k_Omega;
        public TurbBoundTypes? TurbBoundType
        {
            get => _TurbBoundType;
            set
            {
                _TurbBoundType = value;
                RaisePropertyChanged(nameof(TurbBoundType));
                CheckModelSet();
            }
        }
        private TurbBoundTypes? _TurbBoundType = TurbBoundTypes.LowYPlus;


        public BuoyancyTypes? BuoyancyType
        {
            get => _BuoyancyType;
            set
            {
                _BuoyancyType = value;
                RaisePropertyChanged(nameof(BuoyancyType));
                CheckModelSet();
            }
        }
        private BuoyancyTypes? _BuoyancyType = null;
        public RadiationTypes? RadiationType
        {
            get => _RadiationType;
            set
            {
                _RadiationType = value;
                RaisePropertyChanged(nameof(RadiationType));
                CheckModelSet();
            }
        }
        private RadiationTypes? _RadiationType = RadiationTypes.无;
        public DomTypes DomType
        {
            get => _DomType;
            set
            {
                _DomType = value; RaisePropertyChanged(nameof(DomType));
                CheckModelSet();
            }
        }
        private DomTypes _DomType = DomTypes.S4;

        private MaterialProperty _MaterialProperty;
        public MaterialProperty MaterialProperty
        {
            get { return _MaterialProperty; }
            set { _MaterialProperty = value; _MaterialProperty.Parent = this; RaisePropertyChanged(nameof(MaterialProperty)); }
        }
        private ReferenceValue _ReferenceValue;
        public ReferenceValue ReferenceValue
        {
            get { return _ReferenceValue; }
            set { _ReferenceValue = value; _ReferenceValue.Parent = this; RaisePropertyChanged(nameof(ReferenceValue)); }
        }
        private InitialValue _InitialValue;

        public InitialValue InitialValue
        {
            get { return _InitialValue; }
            set { _InitialValue = value; _InitialValue.Parent = this; RaisePropertyChanged(nameof(InitialValue)); }
        }
        private SolveSetting _SolveSetting;

        public SolveSetting SolveSetting
        {
            get { return _SolveSetting; }
            set { _SolveSetting = value; _SolveSetting.Parent = this; RaisePropertyChanged(nameof(SolveSetting)); }
        }
        public override void FromJsonKV(string key, IJsonReader jsReader)
        {
            switch (key)
            {
                case nameof(PhysicalType): PhysicalType = jsReader.ReadEnum<PhysicalTypes>(); break;
                case nameof(IsEnergyEnabled): IsEnergyEnabled = jsReader.ReadBool(); break;
                case nameof(BuoyancyType): BuoyancyType = jsReader.ReadEnum<BuoyancyTypes>(); break;
                case nameof(MaterialProperty): jsReader.ReadObject(MaterialProperty); break;
                case nameof(ReferenceValue): jsReader.ReadObject(ReferenceValue); break;
                case nameof(InitialValue): jsReader.ReadObject(InitialValue); break;
                case nameof(SolveSetting): jsReader.ReadObject(SolveSetting); break;
                default: base.FromJsonKV(key, jsReader); break;
            }
        }
        public override void ToJsonKV(IJsonWriter jsWriter)
        {
            base.ToJsonKV(jsWriter);
            jsWriter.WriteEnum(nameof(PhysicalType), PhysicalType);
            jsWriter.WriteBool(nameof(IsEnergyEnabled), IsEnergyEnabled);
            if (BuoyancyType != null)
            {
                jsWriter.WriteEnum(nameof(BuoyancyType), (BuoyancyTypes)BuoyancyType);
            }
            jsWriter.WriteObject(nameof(MaterialProperty), MaterialProperty);
            jsWriter.WriteObject(nameof(ReferenceValue), ReferenceValue);
            jsWriter.WriteObject(nameof(InitialValue), InitialValue);
            jsWriter.WriteObject(nameof(SolveSetting), SolveSetting);

        }
    }
}